<?php
/**
 * Created by 无所谓已
 * User: Administrator
 * Date: 2025-08-16
 * Time: 21:57
 */

namespace plugin\csauto\app\process;


use plugin\csauto\app\model\DownloaderModel;
use plugin\csauto\app\service\QBittorrentService;
use plugin\csauto\app\service\RssWorkService;
use plugin\csauto\app\service\TaskWorkService;
use plugin\csauto\app\service\LoadBalancerService;
use plugin\csauto\app\service\LoadMonitorService;
use support\Log;
use Workerman\Crontab\Crontab;
use Workerman\Timer;

/**
 * Class RssWorkProcess
 * 步骤 2
 * 对下载器进行任务分配
 * @package plugin\csauto\app\process
 */
class RssWorkProcess
{
    // 定时器句柄/ID
    protected $timer;
    protected $wechatTimer;

    // 时间间隔 (单位: 秒, 默认5秒)
    protected $interval = 90;

    public function onWorkerStart()
    {
        if(getenv('WORK_DEBUG')) return true;
        $this->timer = Timer::add($this->interval, function () {
            try {
                // 这里执行系统预设的定时任务事件
                $this->run();
            } catch (\Throwable $e) {
                echo 'ERROR[RssWorkProcess]: ' . $e->getMessage() . PHP_EOL;
            }
        });

        return true;
    }

    public function run()
    {
        // addlog('下载器-负载均衡分配任务', 'start');

        // 获取所有可用的下载器（负载低于95%的）
        // 0表示返回所有符合条件的下载器，0.95是最大负载阈值
        $availableDownloaders = LoadBalancerService::getAvailableDownloaders(0, 0.95);

        if (empty($availableDownloaders)) {
            addlog('负载均衡', '没有可用的下载器或所有下载器负载过高', 'warning');
            return '任务调用：' . date('Y-m-d H:i:s') . " - 无可用下载器\n";
        }

        addlog('负载均衡', "找到 " . count($availableDownloaders) . " 个可用下载器");

        // 收集所有可用下载器的ID
        $downloaderIds = [];
        foreach ($availableDownloaders as $item) {
            $downloader = $item['downloader'];
            
            // 验证下载器连接和健康状态
            try {
                $qb = QBittorrentService::createService($downloader->id);
                if ($qb) {
                    // 尝试调用API来验证连接是否正常
                    $version = $qb->getVersion();
                    if ($version) {
                        $downloaderIds[] = $downloader->id;
                        addlog('负载均衡', "下载器ID：{$downloader->id}, 负载：" . round($item['load'] * 100, 2) . "% - 可用 (版本: {$version})");
                    } else {
                        addlog('负载均衡', "下载器ID：{$downloader->id} 无法获取版本信息", 'warning');
                    }
                } else {
                    addlog('负载均衡', "下载器ID：{$downloader->id} 无法创建服务", 'warning');
                }
            } catch (\Throwable $e) {
                addlog('负载均衡', "下载器ID：{$downloader->id} 健康检查失败: " . $e->getMessage(), 'warning');
            }
        }

        if (empty($downloaderIds)) {
            addlog('负载均衡', '所有下载器无法连接', 'warning');
            return '任务调用：' . date('Y-m-d H:i:s') . " - 下载器连接失败\n";
        }

        // 批量为多个下载器分配任务
        // 参数1：下载器ID数组
        // 参数2：每个下载器每次最多分配的任务数（3个任务，避免一次性分配过多）
        $stats = TaskWorkService::batchAssignTasks($downloaderIds, 3);

        addlog('任务分配统计', "总计分配：{$stats['total_assigned']} 个任务, 成功：{$stats['successful']}, 失败：{$stats['failed']}");

        // 记录每个下载器的分配详情
        foreach ($stats['details'] as $detail) {
            if (isset($detail['error'])) {
                addlog('任务分配详情', "下载器ID：{$detail['downloader_id']} - 错误：{$detail['error']}");
            } else {
                addlog('任务分配详情', "下载器ID：{$detail['downloader_id']}, 尝试分配：{$detail['attempts']}, 成功分配：{$detail['assigned']}");
            }
        }

        // 记录负载均衡状态和监控报告（简化版，避免重复计算）
        $loads = LoadBalancerService::getAllDownloaderLoads();
        addlog('负载状态汇总', "活跃下载器数量：" . count($loads));
        
        // 只记录参与分配的下载器的负载状态
        foreach ($loads as $load) {
            if (in_array($load['downloader']->id, $downloaderIds)) {
                addlog('负载状态', "下载器ID：{$load['downloader']->id}, 负载评分：" . round($load['load'] * 100, 2) . "%, 活跃任务：{$load['active_tasks']}, 容量使用：" . round($load['capacity_usage']['percentage'], 2) . "%");
            }
        }

        // 生成并记录监控报告
        LoadMonitorService::logLoadReport();

        // 获取负载均衡建议
        $recommendations = LoadMonitorService::getLoadBalancingRecommendations();
        foreach ($recommendations as $recommendation) {
            addlog('负载均衡建议', $recommendation);
        }

        return '任务调用：' . date('Y-m-d H:i:s') . " - 成功分配 {$stats['total_assigned']} 个任务\n";
    }

    /**
     * 停止/删除定时器
     *
     * @return bool
     */
    public function stop()
    {
        return Timer::del($this->timer);
    }

}